独热编码One Hot Encoder

在机器学习时我们通常要进行归一化数据后再进行训练,还有一些其他处理方法比如使用独热编码。

什么是独热码

独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。

可以这样理解,对于每一个特征,如果它有m个可能值,那么经过独热编码后,就变成了m个二元特征。并且,这些特征互斥,每次只有一个激活。因此,数据会变成稀疏的。

例如对六个状态进行编码:

自然顺序码为 000,001,010,011,100,101

独热编码则是 000001,000010,000100,001000,010000,100000

独热码的优点

有一些特征无法直接应用在需要数值计算的算法中,例如,用户的性别,爱好,住址等,一般简单粗暴的处理方式时直接将不同的类别映射为一个整数,比如男性为0,女性为1,其他为2,这种简单的实现最大的问题就在于各种类别的特征都被看成是有序的,这显然不符合实际场景。

使用独热码可以处理非连续型数值特征,并且在一定程度上扩充了特征。

1.使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。

2.将离散特征通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

3.将离散型特征使用one-hot编码,可以会让特征之间的距离计算更加合理。比如,有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理。

编码过程

  假如只有一个特征是离散值:

    {sex:{male, female,other}}

  该特征总共有3个不同的分类值,此时需要3个bit位表示该特征是什么值,对应bit位为1的位置对应原来的特征的值(一般情况下可以将原始的特征的取值进行排序,以便于后期使用),此时得到独热码为{100}男性 ,{010}女性,{001}其他

  假如多个特征需要独热码编码,那么久按照上面的方法依次将每个特征的独热码拼接起来:

    {sex:{male, female,other}}

    {grade:{一年级, 二年级,三年级, 四年级}}

  此时对于输入为{sex:male; grade: 四年级}进行独热编码,可以首先将sex按照上面的进行编码得到{100},然后按照grade进行编码为{0001},那么两者连接起来得到最后的独热码{1000001};   

sklearn中的One Hot Encoder

官方文档

1
2
3
4
5
from sklearn.preprocessing import OneHotEncoder
y = np.array([[1, 2, 3]]).T
encoder = OneHotEncoder(sparse=False)
y_onehot = encoder.fit_transform(y)
print(y_onehot)
1
2
3
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
0%